package internetplus_test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import static java.lang.System.out;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SSLContext;
import javax.security.cert.CertificateException;
import java.security.cert.X509Certificate;  
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLException;  
import javax.net.ssl.SSLSession; 
import javax.net.ssl.SSLSocket;  

import org.json.JSONObject;

/**
 *
 * @author luobo
 */
public class InternetRequest {
//    
//    public static void request_PostWithCookieInHttps(){
//        
//        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager();
//        // 设置连接池  
//        connMgr = new PoolingHttpClientConnectionManager();  
//        // 设置连接池大小  
//        connMgr.setMaxTotal(100);  
//        connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
//        
//        RequestConfig.Builder configBuilder = RequestConfig.custom();  
//        // 设置连接超时  
//        configBuilder.setConnectTimeout(7000);  
//        // 设置读取超时  
//        configBuilder.setSocketTimeout(7000);  
//        // 设置从连接池获取连接实例的超时  
//        configBuilder.setConnectionRequestTimeout(7000);  
//        // 在提交请求之前 测试连接是否可用  
//        configBuilder.setStaleConnectionCheckEnabled(true);  
//        RequestConfig requestConfig = configBuilder.build(); 
//
//        CloseableHttpClient httpClient = HttpClients.custom()
//                .setSSLSocketFactory(createSSLConnSocketFactory())
//                .setConnectionManager(connMgr)
//                .setDefaultRequestConfig(requestConfig)
//                .build();  
//
//    }
    
//    /** 
//     * 创建SSL安全连接 
//     * 
//     * @return 
//     */  
//    private static SSLConnectionSocketFactory createSSLConnSocketFactory() {  
//        SSLConnectionSocketFactory sslsf = null;  
//        try {  
//            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {  
//  
//                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {  
//                    return true;  
//                }  
//            }).build();  
//            sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {  
//  
//                @Override  
//                public boolean verify(String arg0, SSLSession arg1) {  
//                    return true;  
//                }  
//  
//                @Override  
//                public void verify(String host, SSLSocket ssl) throws IOException {  
//                }  
//  
//                @Override  
//                public void verify(String host, X509Certificate cert) throws SSLException {  
//                }  
//  
//                @Override  
//                public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {  
//                }  
//            });  
//        } catch (GeneralSecurityException e) {  
//            e.printStackTrace();  
//        }  
//        return sslsf;  
//    }  

    /**
     *
     * @param httpUrl
     */
    public static void request_getWithoutCookie(String httpUrl) {
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(httpUrl);
            out.println("execute##############################3");
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            out.println(EntityUtils.toString(entity));
        } catch (IOException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     *
     * @param httpUrl
     */
    public static void request_getWithCookie(String httpUrl) {
        BasicClientCookie basicClientCookie = readCookie();
        BasicCookieStore basicCookieStore = new BasicCookieStore();
        basicCookieStore.addCookie(basicClientCookie);
        try {
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(basicCookieStore).build();
            HttpGet httpGet = new HttpGet(httpUrl);
            HttpResponse response = httpClient.execute(httpGet);
            out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ParseException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 传送非文本实体
     *
     * @param httpUrl
     * @param entity
     */
    public static void request_postWithCookie(String httpUrl, FileEntity entity) {
        BasicClientCookie basicClientCookie = readCookie();
        BasicCookieStore basicCookieStore = new BasicCookieStore();
        basicCookieStore.addCookie(basicClientCookie);
        try {
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(basicCookieStore).build();
            HttpPost httpPost = new HttpPost(httpUrl);
            httpPost.setEntity(entity);
            HttpResponse response = httpClient.execute(httpPost);
            out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ParseException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 不添加Cookie进行请求
     *
     * @param httpUrl
     * @param params
     */
    public static void request_postWithoutCookie(String httpUrl, List<NameValuePair> params) {

        try {
            BasicCookieStore cookieStore = new BasicCookieStore();
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore).build();
            HttpPost httpPost = new HttpPost(httpUrl);
            httpPost.setEntity(new UrlEncodedFormEntity(params, "utf-8"));
            HttpResponse response = httpClient.execute(httpPost);
            out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
            
            out.println("###########header相关信息############");
            Header[] headers = response.getAllHeaders();
            for(int i=0; i<headers.length; i++){
                out.println(headers[i].toString());
            }
            out.println("\n"+"#######################");

            
            List<Cookie> cookies = cookieStore.getCookies();
            if (cookies.isEmpty()) {
                out.println("cookie为空！");
            } else {
                out.println("cookie不为空！");
                persistCookie(cookies.get(0));
            }
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ParseException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 添加Cookie进行请求
     *
     * @param httpUrl
     * @param params
     */
    public static void request_postWithCookie(String httpUrl, List<NameValuePair> params) {
        BasicCookieStore basicCookieStore = new BasicCookieStore();
        BasicClientCookie basicClientCookie = readCookie();
//        basicClientCookie.setExpiryDate(null);
        basicCookieStore.addCookie(basicClientCookie);

        try {
            RequestConfig globalConfig = RequestConfig.custom()
                .setCookieSpec(CookieSpecs.STANDARD)
                .build();
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(globalConfig)
                    .setDefaultCookieStore(basicCookieStore)
                    .build();
//            DefaultHttpClient httpClient = new DefaultHttpClient(new PoolingClientConnectionManager());
            HttpPost httpPost = new HttpPost(httpUrl);
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            HttpResponse response = httpClient.execute(httpPost);
            out.println(EntityUtils.toString(response.getEntity(), "utf-8"));
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException | ParseException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * 使用HttpURLConnection请求网络
     *
     * @param httpUrl
     * @param httpArg
     * @throws MalformedURLException
     * @throws IOException
     */
    public static void request(String httpUrl, String httpArg) throws MalformedURLException, IOException {
        BufferedReader reader;
        String result;
        StringBuffer sbf = new StringBuffer();

        URL url = new URL(httpUrl);
        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/Json; charset=UTF-8");
        connection.setDoOutput(true);
        if (httpArg != null) {
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(httpArg.getBytes("UTF-8"));
        }

        out.println("isRight");

        connection.connect();
        InputStream is = connection.getInputStream();
        reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
        String strRead;
        while ((strRead = reader.readLine()) != null) {
            sbf.append(strRead);
            sbf.append("\n");
        }
        reader.close();
        result = sbf.toString();
        out.println(result);
    }

    /**
     * @return
     */
    @SuppressWarnings("null")
    public static BasicClientCookie readCookie() {
        BasicClientCookie cookie;
        FileInputStream in = null;
        try {
            File file = new File("Cookie.json");
            in = new FileInputStream(file);
            byte[] temp;
            temp = new byte[1024];
            in.read(temp);
            String jsonString = new String(temp).trim();
            out.println("cookie字符串----->" + jsonString);
            JSONObject jsonObject = new JSONObject(jsonString);
            cookie = new BasicClientCookie(jsonObject.getString("name"), null);
            if (!jsonObject.isNull("comment")) {
                cookie.setComment(jsonObject.getString("comment"));
            }
            if (!jsonObject.isNull("domain")) {
                cookie.setDomain(jsonObject.getString("domain"));
            }
            if (!jsonObject.isNull("expiryDate")) {
                cookie.setExpiryDate(new Date(jsonObject.getString("expiryDate")));
            }
            if (!jsonObject.isNull("path")) {
                cookie.setPath(jsonObject.getString("path"));
            }
            if (!jsonObject.isNull("value")) {
                cookie.setValue(jsonObject.getString("value"));
            }
            if (!jsonObject.isNull("version")) {
                int version = jsonObject.getInt("version");
                cookie.setVersion(version);
            }
            return cookie;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                in.close();
            } catch (IOException ex) {
                Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        return null;
    }

    /**
     * 将cookie持久化
     *
     * @param cookie
     */
    public static void persistCookie(Cookie cookie) {

        out.println(cookie.toString());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("comment", cookie.getComment());
        jsonObject.put("commentUrl", cookie.getCommentURL());
        jsonObject.put("domain", cookie.getDomain());
        jsonObject.put("expiryDate", cookie.getExpiryDate());
        jsonObject.put("name", cookie.getName());
        jsonObject.put("path", cookie.getPath());
        jsonObject.put("ports", cookie.getPorts());
        jsonObject.put("value", cookie.getValue());
        jsonObject.put("version", cookie.getVersion());

        String jsonString = jsonObject.toString();

        FileOutputStream out = null;
        try {
            File file = new File("Cookie.json");
            out = new FileOutputStream(file);
            out.write(jsonString.getBytes());
        } catch (FileNotFoundException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                out.close();
            } catch (IOException ex) {
                Logger.getLogger(InternetRequest.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

}
